package com.ww.springboot.boot.thread.threadlocal;

import com.alibaba.ttl.TransmittableThreadLocal;
import com.alibaba.ttl.threadpool.TtlExecutors;

import java.util.concurrent.*;

/**
 * 描述：
 *  * 描述：InheritableThreadLocal原理
 *  * 在创建线程时 会复制父线程的InheritableThreadLocal值
 *  * 但是线程池中的线程只会创建一次 如果另外的父线程想传递值给子线程 那么子线程无法获取
 *
 * @author 🧑 ‍wanwei
 * @since 2025-08-21 09:55
 */
public class 线程池线程父子关系 {

    private static final InheritableThreadLocal<String> inheritableThreadLocal = new InheritableThreadLocal();

    /**
     * TransmittableThreadLocal 需要配合TtlExecutors 使用才能生效 不然跟InheritableThreadLocal没区别
     * 源码暂未阅读！！！！！！
     */
    private static final TransmittableThreadLocal<String> transmittableThreadLocal = new TransmittableThreadLocal();


    private static final ThreadPoolExecutor t = new ThreadPoolExecutor(1, 1, 1
            , TimeUnit.SECONDS, new ArrayBlockingQueue<>(10));

    private static final ExecutorService t2  = TtlExecutors.getTtlExecutorService(t);
    public static void main(String[] args) {
        //test1();
        test2();
    }

    private static void test1() {
        inheritableThreadLocal.set("123");
        transmittableThreadLocal.set("123");
        //System.out.println(Thread.currentThread() + " " + inheritableThreadLocal.get());
        t.execute(() -> {
            System.out.println(Thread.currentThread() + " inheritableThreadLocal1 " + inheritableThreadLocal.get());
            System.out.println(Thread.currentThread() + " transmittableThreadLocal1 " + transmittableThreadLocal.get());
            t.execute(() -> {
                System.out.println(Thread.currentThread() + " inheritableThreadLocal1 " + inheritableThreadLocal.get());
                System.out.println(Thread.currentThread() + " transmittableThreadLocal1 " + transmittableThreadLocal.get());
            });
        });

        new Thread(() -> {
            inheritableThreadLocal.set("789");
            transmittableThreadLocal.set("789");
            t.execute(() -> {
                //inheritableThreadLocal子线程无法获取父线程的InheritableThreadLocal值 因为已经被初始化过了
                System.out.println(Thread.currentThread() + " inheritableThreadLocal2 " + inheritableThreadLocal.get());
                //transmittableThreadLocal 源码待学习
                System.out.println(Thread.currentThread() + " transmittableThreadLocal2 " + transmittableThreadLocal.get());
                t.execute(() -> {
                    System.out.println(Thread.currentThread() + " inheritableThreadLocal2 " + inheritableThreadLocal.get());
                    System.out.println(Thread.currentThread() + " transmittableThreadLocal2 " + transmittableThreadLocal.get());
                });
            });
        }).start();
    }

    private static void test2() {
        inheritableThreadLocal.set("123");
        transmittableThreadLocal.set("123");
        //System.out.println(Thread.currentThread() + " " + inheritableThreadLocal.get());
        t2.execute(() -> {
            System.out.println(Thread.currentThread() + " inheritableThreadLocal1 " + inheritableThreadLocal.get());
            System.out.println(Thread.currentThread() + " transmittableThreadLocal1 " + transmittableThreadLocal.get());
            t2.execute(() -> {
                System.out.println(Thread.currentThread() + " inheritableThreadLocal1 " + inheritableThreadLocal.get());
                System.out.println(Thread.currentThread() + " transmittableThreadLocal1 " + transmittableThreadLocal.get());
            });
        });

        new Thread(() -> {
            inheritableThreadLocal.set("789");
            transmittableThreadLocal.set("789");
            t2.execute(() -> {
                //inheritableThreadLocal子线程无法获取父线程的InheritableThreadLocal值 因为已经被初始化过了
                System.out.println(Thread.currentThread() + " inheritableThreadLocal2 " + inheritableThreadLocal.get());
                //transmittableThreadLocal 源码待学习
                System.out.println(Thread.currentThread() + " transmittableThreadLocal2 " + transmittableThreadLocal.get());
                t2.execute(() -> {
                    System.out.println(Thread.currentThread() + " inheritableThreadLocal2 " + inheritableThreadLocal.get());
                    System.out.println(Thread.currentThread() + " transmittableThreadLocal2 " + transmittableThreadLocal.get());
                });
            });
        }).start();
    }
}
